﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Diagnostics;
using IlianaRuler.DAL;
using IlianaRuler.Utils;

namespace IlianaRuler.CPL
{
    /// <summary>
    /// 命令类型
    /// </summary>
    public enum CommandType : byte
    {
        /// <summary>
        /// 登录
        /// </summary>
        Login                   = 0x01,
        /// <summary>
        /// 登出
        /// </summary>
        Logout                  = 0x02,
        /// <summary>
        /// 注册节点
        /// </summary>
        RegisterNode            = 0x03,
        /// <summary>
        /// 更新节点
        /// </summary>
        UpdateNode              = 0x04,
        /// <summary>
        /// 删除节点
        /// </summary>
        RemoveNode              = 0x05,
        /// <summary>
        /// 校时
        /// </summary>
        Timing                  = 0x06,
        /// <summary>
        /// 设置策略
        /// </summary>
        SetTactics              = 0x07,
        /// <summary>
        /// 控制状态
        /// </summary>
        Control                 = 0x08,
        /// <summary>
        /// 获取状态
        /// </summary>
        GetStatus               = 0x09,
        /// <summary>
        /// 自检
        /// </summary>
        SelfChecking            = 0x0a,
        /// <summary>
        /// 告警
        /// </summary>
        Alert                   = 0x0f,
        /// <summary>
        /// 无操作(心跳)
        /// </summary>
        Noop                    = 0xff
    }

    /// <summary>
    /// 通讯层指令执行错误代码
    /// </summary>
    public enum ErrorCode : ushort
    {
        /// <summary>
        /// 执行成功
        /// </summary>
        Success                 = 0x0000,
        /// <summary>
        /// 通讯失败
        /// </summary>
        SocketFailed            = 0x0001,
        /// <summary>
        /// 无效的SmartServer
        /// </summary>
        InvalidServer           = 0x0002,
        /// <summary>
        /// 写入失败
        /// </summary>
        WriteFailed             = 0x0003,
        /// <summary>
        /// 无效的节点(别名)
        /// </summary>
        InvalidNode             = 0x3001,
        /// <summary>
        /// 节点NeruonID已被使用
        /// </summary>
        UsedNeruonID            = 0x3002,
        /// <summary>
        /// 绑定告警服务器失败
        /// </summary>
        BindAlertServerFailed   = 0x4001,
        /// <summary>
        /// 重复注册的节点(别名)
        /// </summary>
        ReduplicateNode         = 0x4002,
        /// <summary>
        /// 无效的控制指令
        /// </summary>
        InvalidCommand          = 0x2001,
        /// <summary>
        /// 数据采集失败
        /// </summary>
        CollectDataFailed       = 0x1301,
        /// <summary>
        /// 未连接或连接丢失
        /// </summary>
        Disconnected            = 0x9001,
        /// <summary>
        /// 未登录的客户
        /// </summary>
        NotLogin                = 0x9002,
        /// <summary>
        /// 登录失败（用户名或密码不正确）
        /// </summary>
        LoginFailed             = 0x9003,
        /// <summary>
        /// 等待应答超时
        /// </summary>
        ResponseTimeout         = 0x9004,
        /// <summary>
        /// 未知错误
        /// </summary>
        Unknown                 = 0x0099
    }

    /// <summary>
    /// 校时类型
    /// </summary>
    public enum TimingType : byte
    {
        /// <summary>
        /// 指定SmartServer及其它所有节点
        /// </summary>
        Specified               = 0x01,
        /// <summary>
        /// 指定的节点
        /// </summary>
        Node                    = 0x02,
        /// <summary>
        /// 全部SmartServer及节点
        /// </summary>
        All                     = 0x03
    }

    /// <summary>
    /// 自检类型
    /// </summary>
    public enum SelfCheckingType : byte
    {
        /// <summary>
        /// 检测SmartServer
        /// </summary>
        Server                  = 0x01,
        /// <summary>
        /// 检测节点
        /// </summary>
        Node                    = 0x02
    }

    /// <summary>
    /// 策略规则类
    /// </summary>
    public struct TacticRule
    {
        /// <summary>
        /// 触发时间
        /// </summary>
        public DateTime Time;

        /// <summary>
        /// 设置状态
        /// </summary>
        public Single State;

        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="time"></param>
        /// <param name="state"></param>
        public TacticRule(DateTime time, Single state)
        {
            Time = time;
            State = state;
        }
    }

    /// <summary>
    /// 节点状态
    /// </summary>
    public struct NodeStatus
    {
        /// <summary>
        /// 电压
        /// </summary>
        public Single Voltage;
        /// <summary>
        /// 电流
        /// </summary>
        public Single Current;
        /// <summary>
        /// 灯源电压
        /// </summary>
        public Single LampVoltage;
        /// <summary>
        /// 灯源电流
        /// </summary>
        public Single LampCurrent;
        /// <summary>
        /// 功率因素
        /// </summary>
        public Single PowerFactor;
        /// <summary>
        /// 功率（计算值）
        /// </summary>
        public Single Powers;
        /// <summary>
        /// 温度
        /// </summary>
        public byte Temperature;
        /// <summary>
        /// 运行时间
        /// </summary>
        public int RunHours;
        /// <summary>
        /// 总能耗
        /// </summary>
        public int Energy;
        /// <summary>
        /// 状态
        /// </summary>
        public Single State;
    }

    static class StreamReaderExtensions
    {
        /// <summary>
        /// 向流中写入字符串
        /// </summary>
        /// <param name="streamWriter"></param>
        /// <param name="str"></param>
        /// <remarks>字符串型数据采用 [长度][ASCII编码] 方式传输</remarks>
        public static void WriteString(this BinaryWriter streamWriter, string str)
        {
            if (str.Length > 255)
            {
                throw new ArgumentOutOfRangeException("str");
            }

            streamWriter.Write((byte)str.Length);
            streamWriter.Write(Encoding.ASCII.GetBytes(str));
        }
    }

    /// <summary>
    /// 管理请求协议并处理超时的类
    /// </summary>
    static class RequestManager
    {
        private static Dictionary<Guid, BaseProtocol> _requests = new Dictionary<Guid, BaseProtocol>();
        /// <summary>
        /// 请求存活时长（秒）
        /// </summary>
        private const int LifeTime = 20;

        /// <summary>
        /// 清除超时的请求
        /// </summary>
        public static void ClearTimeoutRequest()
        {
            lock(_requests)
            {
                int i = 0;
                while(i < _requests.Count)
                {
                    BaseProtocol p = _requests.ElementAt(i).Value;
                    if((DateTime.Now - p.BuildTime).TotalSeconds > LifeTime)
                    {
                        _requests.Remove(p.ID);
                        try
                        {
                            Business.UpdateHistory(p.ID, ErrorCode.ResponseTimeout);
                        }
                        catch
                        {

                        }
                        Debug.Print("清除超时协议对象 " + p.ID);
                    }
                    else
                    {
                        i++;
                    }
                }
            }
            GC.Collect();
        }

        /// <summary>
        /// 注册一个新的请求
        /// </summary>
        /// <param name="p"></param>
        public static void RegisterRequest(BaseProtocol p)
        {
            lock(_requests)
            {
                _requests.Add(p.ID, p);
            }
        }

        /// <summary>
        /// 从请求池中找出指定ID的协议对象并从池中剔除
        /// </summary>
        /// <param name="id"></param>
        /// <returns>成功返回协议对象，失败返回NULL</returns>
        public static BaseProtocol Popup(Guid id)
        {
            lock(_requests)
            {
                if(_requests.ContainsKey(id))
                {
                    BaseProtocol p = _requests[id];
                    _requests.Remove(id);
                    return p;
                }

                return null;
            }
        }

        /// <summary>
        /// 确定指定ID的协议对象是否存在于池中
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static bool FindRequest(Guid id)
        {
            return _requests.ContainsKey(id);
        }
    }

    /// <summary>
    /// 通讯协议基类
    /// </summary>
    /// <remarks>
    /// 协议基本格式：
    ///     ID(16 bytes)|CommandType(1 byte)|Length(4 bytes)|Content
    ///     指令流水     指令类型            协议包的总长度  包体    
    ///     －－检验码是对指令字和用户ID的MD5数据
    ///     
    ///     请求和应答均采用上述格式。
    /// </remarks>
    abstract class BaseProtocol
    {
        protected Guid _id;
        CommandType _type;
        ErrorCode _state = ErrorCode.Unknown;
        DateTime _buildTime;

        protected BaseProtocol(CommandType type)
        {
            _id = Guid.NewGuid();
            _type = type;
        }

        /// <summary>
        /// 写入请求流包体
        /// </summary>
        /// <param name="streamWriter"></param>
        protected virtual void WriteRequest(BinaryWriter streamWriter)
        {

        }

        /// <summary>
        /// 读取应答流中的包体部份
        /// </summary>
        /// <param name="streamReader"></param>
        protected virtual void ReadResponse(BinaryReader streamReader)
        {

        }

        /// <summary>
        /// 生成请求包后的处理过程
        /// </summary>
        protected virtual void RequestProcess()
        {

        }

        /// <summary>
        /// 解析应答包后的处理过程
        /// </summary>
        protected virtual void ResponseProcess()
        {
            
        }

        /// <summary>
        /// 从流中读取字符串
        /// </summary>
        /// <param name="streamReader"></param>
        /// <returns></returns>
        /// <remarks>字符串型数据采用 [长度][ASCII编码] 方式传输</remarks>
        protected static string ReadString(BinaryReader streamReader)
        {
            byte len = streamReader.ReadByte();
            byte[] buf = streamReader.ReadBytes(len);
            return Encoding.ASCII.GetString(buf);
        }

        /// <summary>
        /// 命令ID
        /// </summary>
        public Guid ID
        {
            get { return _id; }
        }

        /// <summary>
        /// 命令类型
        /// </summary>
        public CommandType Type
        {
            get { return _type; }
        }

        /// <summary>
        /// 协议构建时间（用于判断等待超时）
        /// </summary>
        public DateTime BuildTime
        {
            get { return _buildTime; }
        }

        /// <summary>
        /// 执行状态，在未收到返回前为Unknown
        /// </summary>
        public ErrorCode State
        {
            get { return _state; }
        }

        /// <summary>
        /// 获取协议的二进度数据
        /// </summary>
        /// <returns></returns>
        public byte[] GetRequest()
        {
            MemoryStream ms = new MemoryStream();
            BinaryWriter bw = new BinaryWriter(ms);

            //写入包头
            //写入ID
            bw.Write(_id.ToByteArray());
            //写入命令类型
            bw.Write((byte)_type);
            //写入包长度占位符
            bw.Write(0x00000000);

            //写入包体
            WriteRequest(bw);

            //重新写入实际长度
            bw.Seek(17, SeekOrigin.Begin);
            bw.Write((uint)ms.Length);

            //设置构建时间，用于超时处理
            _buildTime = DateTime.Now;

            //登记本请求
            RequestManager.RegisterRequest(this);

            RequestProcess();

            return ms.ToArray();
        }

        /// <summary>
        /// 解析应答包
        /// </summary>
        /// <param name="dataBuffer"></param>
        public void ParseResponse(byte[] dataBuffer, int len)
        {
            MemoryStream ms = new MemoryStream(dataBuffer, 0, len);
            BinaryReader br = new BinaryReader(ms);

            //读取包头
            //读入包长度
            ms.Seek(17, SeekOrigin.Begin); //略过ID和类型
            uint l = br.ReadUInt32();

            if (l != len)
                throw new Exception("incorrect datagram length");

            _state = (ErrorCode)br.ReadUInt16();

            ReadResponse(br);

            ResponseProcess();
        }

        public static Guid GetResponseID(byte[] dataBuffer, int len)
        {
            Debug.Assert(len >= 23);
            byte[] idBytes = new byte[16];
            Array.ConstrainedCopy(dataBuffer, 0, idBytes, 0, 16);
            return new Guid(idBytes);
        }

        public static CommandType GetResponseType(byte[] dataBuffer, int len)
        {
            Debug.Assert(len >= 23);
            return (CommandType)dataBuffer[16];
        }
    }

    /// <summary>
    /// 登录认证
    /// </summary>
    /// <remarks>
    /// 登录请求协议如下：
    ///     PkgHeader(21 bytes)|CustomerID(n bytes)|Password(16 bytes)
    ///     包头                用户ID              密码(MD5)
    /// </remarks>
    class LoginProtocol : BaseProtocol
    {
        private string _customerId;
        private byte[] _password;

        public string CustomerID
        {
            get { return _customerId; }
        }

        public LoginProtocol(string customerId, byte[] password) : base(CommandType.Login)
        {
            _customerId = customerId;
            _password = password;
            //修改为固定的ID以标识登录协议
            //_id = new Guid(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
        }

        protected override void WriteRequest(BinaryWriter streamWriter)
        {
            streamWriter.WriteString(_customerId);
            streamWriter.Write(_password);
        }
    }

    /// <summary>
    /// 注册节点协议类
    /// </summary>
    class RegisterNodeProtocol : BaseProtocol
    {
        private byte _nodeType;
        private string _serverIp;
        private string _nodeName;
        private string _neruonID;
        private bool _bindAlert;

        public byte NodeType
        {
            get { return _nodeType; }
        }

        public string ServerIP
        {
            get { return _serverIp; }
        }

        public string NodeName
        {
            get { return _nodeName; }
        }

        public string NeruonID
        {
            get { return _neruonID; }
        }

        public bool BindAlert
        {
            get { return _bindAlert; }
        }

        public RegisterNodeProtocol(byte nodeType, string serverIp,
            string nodeName, string neruonID, bool bindAlert)
            : base(CommandType.RegisterNode)
        {
            _nodeType = nodeType;
            _serverIp = serverIp;
            _nodeName = nodeName;
            _neruonID = neruonID;
            _bindAlert = bindAlert;
        }

        protected override void WriteRequest(BinaryWriter streamWriter)
        {
            streamWriter.Write(_nodeType);
            streamWriter.WriteString(_serverIp);
            streamWriter.WriteString(_nodeName);
            streamWriter.WriteString(_neruonID);
            streamWriter.Write(_bindAlert);
        }

        protected override void RequestProcess()
        {
            Business.RegisterHistory(ID, Type, _serverIp, _nodeName);
        }

        protected override void ResponseProcess()
        {
            Business.UpdateHistory(ID, State);
            Business.RegisterNode(ID, NodeType, ServerIP, NodeName, NeruonID, BindAlert, State);
            Utility.Debug(String.Format("RegisterNode {0} Response {1}", ID.ToString(), State.ToString()));
        }
    }

    /// <summary>
    /// 注册节点协议类
    /// </summary>
    class UpdateNodeProtocol : BaseProtocol
    {
        private byte _nodeType;
        private string _serverIp;
        private string _nodeName;
        private string _neruonID;

        public byte NodeType
        {
            get { return _nodeType; }
        }

        public string ServerIP
        {
            get { return _serverIp; }
        }

        public string NodeName
        {
            get { return _nodeName; }
        }

        public string NeruonID
        {
            get { return _neruonID; }
        }

        public UpdateNodeProtocol(byte nodeType, string serverIp,
            string nodeName, string neruonID)
            : base(CommandType.UpdateNode)
        {
            _nodeType = nodeType;
            _serverIp = serverIp;
            _nodeName = nodeName;
            _neruonID = neruonID;
        }

        protected override void WriteRequest(BinaryWriter streamWriter)
        {
            streamWriter.Write(_nodeType);
            streamWriter.WriteString(_serverIp);
            streamWriter.WriteString(_nodeName);
            streamWriter.WriteString(_neruonID);
        }

        protected override void RequestProcess()
        {
            Business.RegisterHistory(ID, Type, _serverIp, _nodeName);
        }

        protected override void ResponseProcess()
        {
            Business.UpdateHistory(ID, State);
            Business.UpdateNode(ID, NodeType, ServerIP, NodeName, NeruonID, State);
            Utility.Debug(String.Format("UpdateNode {0} Response {1}", ID.ToString(), State.ToString()));
        }
    }

    /// <summary>
    /// 删除节点协议类
    /// </summary>
    class RemoveNodeProtocol : BaseProtocol
    {
        private byte _nodeType;
        private string _serverIp;
        private string _nodeName;

        public byte NodeType
        {
            get { return _nodeType; }
        }

        public string ServerIP
        {
            get { return _serverIp; }
        }

        public string NodeName
        {
            get { return _nodeName; }
        }

        public RemoveNodeProtocol(byte nodeType, string serverIp,
            string nodeName)
            : base(CommandType.RemoveNode)
        {
            _nodeType = nodeType;
            _serverIp = serverIp;
            _nodeName = nodeName;
        }

        protected override void WriteRequest(BinaryWriter streamWriter)
        {
            streamWriter.Write(_nodeType);
            streamWriter.WriteString(_serverIp);
            streamWriter.WriteString(_nodeName);
        }

        protected override void RequestProcess()
        {
            Business.RegisterHistory(ID, Type, _serverIp, _nodeName);
        }

        protected override void ResponseProcess()
        {
            Business.UpdateHistory(ID, State);
            Business.RemoveNode(ID, NodeType, ServerIP, NodeName, State);
            Utility.Debug(String.Format("RemoveNode {0} Response {1}", ID.ToString(), State.ToString()));
        }
    }

    /// <summary>
    /// 删除节点协议类
    /// </summary>
    class TimingProtocol : BaseProtocol
    {
        private byte _nodeType;
        private string _serverIp;
        private string _nodeName;
        private TimingType _timingType;

        public byte NodeType
        {
            get { return _nodeType; }
        }

        public string ServerIP
        {
            get { return _serverIp; }
        }

        public string NodeName
        {
            get { return _nodeName; }
        }

        public TimingType TimingType
        {
            get { return _timingType; }
        }

        public TimingProtocol(byte nodeType, string serverIp,
            string nodeName, TimingType timingType)
            : base(CommandType.Timing)
        {
            _nodeType = nodeType;
            _serverIp = serverIp;
            _nodeName = nodeName;
            _timingType = timingType;
        }

        protected override void WriteRequest(BinaryWriter streamWriter)
        {
            streamWriter.Write(_nodeType);
            streamWriter.WriteString(_serverIp);
            streamWriter.WriteString(_nodeName);
            streamWriter.Write((byte)_timingType);
        }

        protected override void RequestProcess()
        {
            Business.RegisterHistory(ID, Type, _serverIp, _nodeName);
        }

        protected override void ResponseProcess()
        {
            Business.UpdateHistory(ID, State);
            Utility.Debug(String.Format("Timing {0} Response {1}", ID.ToString(), State.ToString()));
        }
    }

    /// <summary>
    /// 设置策略协议类
    /// </summary>
    class SetTacticsProtocol : BaseProtocol
    {
        private byte _nodeType;
        private string _serverIp;
        private bool _valid;
        private TacticRule[] _rules;
        private string[] _nodes;
        private byte[] _weekDays;

        public byte NodeType
        {
            get { return _nodeType; }
        }

        public bool Valid
        {
            get { return _valid; }
        }

        public TacticRule[] Rules
        {
            get { return _rules; }
        }

        public string[] Nodes
        {
            get { return _nodes; }
        }

        public byte[] WeekDays
        {
            get { return _weekDays; }
        }

        public SetTacticsProtocol(byte nodeType, string serverIp,
            bool valid, byte[] weekDays, TacticRule[] rules,
            string[] nodes)
            : base(CommandType.SetTactics)
        {
            _nodeType = nodeType;
            _serverIp = serverIp;
            _valid = valid;
            _rules = rules;
            _nodes = nodes;
            _weekDays = weekDays;
        }

        protected override void WriteRequest(BinaryWriter streamWriter)
        {
            streamWriter.Write(_nodeType);
            streamWriter.WriteString(_serverIp);
            streamWriter.Write(_valid);

            streamWriter.Write((byte)_weekDays.Count());
            foreach(byte b in _weekDays)
            {
                streamWriter.Write(b);
            }

            streamWriter.Write((byte)_rules.Count());
            foreach(TacticRule r in _rules)
            {
                streamWriter.WriteString(r.Time.ToString("yyyy-MM-dd HH:mm:ss"));
                streamWriter.WriteString(r.State.ToString());
            }
            streamWriter.Write((ushort)_nodes.Count());
            foreach(string s in _nodes)
            {
                streamWriter.WriteString(s);
            }
        }

        protected override void RequestProcess()
        {
            Business.RegisterHistory(ID, Type, _serverIp, "");
        }

        protected override void ResponseProcess()
        {
            Business.UpdateHistory(ID, State);
            Utility.Debug(String.Format("SetTactics {0} Response {1}", ID.ToString(), State.ToString()));
        }
    }

    /// <summary>
    /// 控制节点协议类
    /// </summary>
    class ControlProtocol : BaseProtocol
    {
        private byte _nodeType;
        private string _serverIp;
        private string _nodeName;
        private float _nodeState;

        public byte NodeType
        {
            get { return _nodeType; }
        }

        public string ServerIP
        {
            get { return _serverIp; }
        }

        public string NodeName
        {
            get { return _nodeName; }
        }

        public float NodeState
        {
            get { return _nodeState; }
        }

        public ControlProtocol(byte nodeType, string serverIp,
            string nodeName, float nodeState)
            : base(CommandType.Control)
        {
            _nodeType = nodeType;
            _serverIp = serverIp;
            _nodeName = nodeName;
            _nodeState = nodeState;
        }

        protected override void WriteRequest(BinaryWriter streamWriter)
        {
            streamWriter.Write(_nodeType);
            streamWriter.WriteString(_serverIp);
            streamWriter.WriteString(_nodeName);
            streamWriter.WriteString(_nodeState.ToString());
        }

        protected override void RequestProcess()
        {
            Business.RegisterHistory(ID, Type, _serverIp, _nodeName);
        }

        protected override void ResponseProcess()
        {
            Business.UpdateHistory(ID, State);
            Business.Control(ID, NodeType, _serverIp, _nodeName, _nodeState, State);
            Utility.Debug(String.Format("Control {0} Response {1}", ID.ToString(), State.ToString()));
        }
    }

    /// <summary>
    /// 心跳协议类
    /// </summary>
    class NoopProtocol : BaseProtocol
    {
        public NoopProtocol()
            : base(CommandType.Noop)
        {
        }
    }

    /// <summary>
    /// 获取节点状态协议类
    /// </summary>
    class GetStatusProtocol : BaseProtocol
    {
        private byte _nodeType;
        private string _serverIp;
        private string _nodeName;
        private NodeStatus _nodeStatus;

        public byte NodeType
        {
            get { return _nodeType; }
        }

        public string ServerIP
        {
            get { return _serverIp; }
        }

        public string NodeName
        {
            get { return _nodeName; }
        }

        public GetStatusProtocol(byte nodeType, string serverIp,
            string nodeName)
            : base(CommandType.GetStatus)
        {
            _nodeType = nodeType;
            _serverIp = serverIp;
            _nodeName = nodeName;
        }

        protected override void WriteRequest(BinaryWriter streamWriter)
        {
            streamWriter.Write(_nodeType);
            streamWriter.WriteString(_serverIp);
            streamWriter.WriteString(_nodeName);
        }

        protected override void ReadResponse(BinaryReader streamReader)
        {
            if(State == ErrorCode.Success)
            {
                _nodeStatus.Voltage = float.Parse(ReadString(streamReader));
                _nodeStatus.Current = float.Parse(ReadString(streamReader));
                _nodeStatus.LampVoltage = float.Parse(ReadString(streamReader));
                _nodeStatus.LampCurrent = float.Parse(ReadString(streamReader));
                _nodeStatus.PowerFactor = float.Parse(ReadString(streamReader));
                _nodeStatus.Powers = float.Parse(ReadString(streamReader));
                _nodeStatus.Temperature = streamReader.ReadByte();
                _nodeStatus.RunHours = streamReader.ReadInt32();
                _nodeStatus.Energy = streamReader.ReadInt32();
                _nodeStatus.State = float.Parse(ReadString(streamReader));
            }
        }

        protected override void RequestProcess()
        {
            Business.RegisterHistory(ID, Type, _serverIp, _nodeName);
        }

        protected override void ResponseProcess()
        {
            Business.UpdateHistory(ID, State);
            Business.GetStatus(ID, NodeType, ServerIP, NodeName, _nodeStatus, State);
            Utility.Debug(String.Format("GetStatus {0} Response {1}", ID.ToString(), State.ToString()));
        }
    }

    /// <summary>
    /// 自检协议类
    /// </summary>
    class SelfCheckingProtocol : BaseProtocol
    {
        private byte _nodeType;
        private string _serverIp;
        private string _nodeName;
        private SelfCheckingType _checkingType;
        private int _result;

        public byte NodeType
        {
            get { return _nodeType; }
        }

        public string ServerIP
        {
            get { return _serverIp; }
        }

        public string NodeName
        {
            get { return _nodeName; }
        }

        public SelfCheckingType CheckingType
        {
            get { return _checkingType; }
        }

        public int Result
        {
            get { return _result; }
        }

        public SelfCheckingProtocol(byte nodeType, string serverIp,
            string nodeName, SelfCheckingType checkingType)
            : base(CommandType.SelfChecking)
        {
            _nodeType = nodeType;
            _serverIp = serverIp;
            _nodeName = nodeName;
            _checkingType = checkingType;
        }

        protected override void WriteRequest(BinaryWriter streamWriter)
        {
            streamWriter.Write(_nodeType);
            streamWriter.WriteString(_serverIp);
            streamWriter.WriteString(_nodeName);
            streamWriter.Write((byte)_checkingType);
        }

        protected override void ReadResponse(BinaryReader streamReader)
        {
            if(State == ErrorCode.Success)
            {
                _result = streamReader.ReadInt32();
            }
        }

        protected override void RequestProcess()
        {
            Business.RegisterHistory(ID, Type, _serverIp, _nodeName);
        }

        protected override void ResponseProcess()
        {
            Business.UpdateHistory(ID, State);
            Business.SelfChecking(ID, NodeType, ServerIP, NodeName, _checkingType, State, _result);
            Utility.Debug(String.Format("SelfChecking {0} Response {1}", ID.ToString(), State.ToString()));
        }
    }

    /// <summary>
    /// 获取节点状态协议类
    /// </summary>
    class AlertProtocol : BaseProtocol
    {
        private byte _nodeType = 0;
        private string _serverIp = "";
        private string _nodeName = "";
        private short _alertType = 0;
        private NodeStatus _nodeStatus;
        private DateTime _alertTime = DateTime.Now;

        public byte NodeType
        {
            get { return _nodeType; }
        }

        public string ServerIP
        {
            get { return _serverIp; }
        }

        public string NodeName
        {
            get { return _nodeName; }
        }

        public short AlertType
        {
            get { return _alertType; }
        }

        public DateTime AlertTime
        {
            get { return _alertTime; }
        }

        public AlertProtocol(Guid id)
            : base(CommandType.Alert)
        {
            _id = id;
        }
        
        protected override void  WriteRequest(BinaryWriter streamWriter)
        {
 	         base.WriteRequest(streamWriter);
        }

        protected override void ReadResponse(BinaryReader streamReader)
        {
            if (State == ErrorCode.Success)
            {
                _serverIp = ReadString(streamReader);
                _nodeName = ReadString(streamReader);
                _alertType = streamReader.ReadInt16();
                _alertTime = DateTime.Parse(ReadString(streamReader));

                _nodeStatus.Voltage = float.Parse(ReadString(streamReader));
                _nodeStatus.Current = float.Parse(ReadString(streamReader));
                _nodeStatus.LampVoltage = float.Parse(ReadString(streamReader));
                _nodeStatus.LampCurrent = float.Parse(ReadString(streamReader));
                _nodeStatus.PowerFactor = float.Parse(ReadString(streamReader));
                _nodeStatus.Powers = float.Parse(ReadString(streamReader));
                _nodeStatus.Temperature = streamReader.ReadByte();
                _nodeStatus.RunHours = streamReader.ReadInt32();
                _nodeStatus.Energy = streamReader.ReadInt32();
                _nodeStatus.State = float.Parse(ReadString(streamReader));
            }
        }

        protected override void RequestProcess()
        {
        }

        protected override void ResponseProcess()
        {
            Business.RegisterHistory(ID, Type, _serverIp, _nodeName);
            Business.UpdateHistory(ID, State);
            Business.Alert(ID, _nodeType, _serverIp, _nodeName, _alertType, _alertTime, _nodeStatus);
            Utility.Debug(String.Format("Alert {0} Response {1}", ID.ToString(), State.ToString()));
        }
    }

}
